# -*- coding: utf-8 -*-

# This code is licensed under GNU GPL v3: http://www.gnu.org/copyleft/gpl.html

__all__ = ['dbm', 'gae']

import anydbm, json

from __init__ import storage

class dbm(storage):
    """anydbm-based database backend."""
    def __init__(self, path):
        self.__path = path
        self.__dbm = anydbm.open(path, 'c', 0700)
        self.__cache = {}

    def __getitem__(self, k):
        if k not in self.__cache.keys():
            self.__cache[k] = self.__dbm[k]

        return json.loads(self.__cache[k])

    def __setitem__(self, k, v):
        self.__cache[k] = json.dumps(v)

    def __delitem__(self, k):
        del self.__cache[k]

    def rollback(self):
        self.__cache = {}

    def sync(self):
        self.__dbm.update(self.__cache)
        self.__dbm.close()
        self.__init__(self.__path)

    def close(self):
        self.__dbm.close()

    def __del__(self):
        self.sync()
        self.close()

try:
    from google.appengine.ext import db

    class GAEEntity(db.Model):
        keyname = db.StringProperty()
        value = db.TextProperty()


    class gae(storage):
        """Google App Engine database backend."""
        __cache = {}
        __dels = []

        def __init__(self): pass

        def __getitem__(self, k):
            if k not in self.__cache.keys():
                self.__cache[k] = GAEEtity.all().filter('keyname =', k)[0].value

            return json.loads(self.__cache[k])


        def __setitem__(self, k, v):
            self.__cache[k] = json.dumps(v)

        def __delitem__(self, k):
            if k not in self.__dels:
                self.__dels.append(k)

        def rollback(self):
            self.__cache = {}
            self.__dels = []

        def sync(self):
            for k, v in self.__cache.items():
                entity = GAEEntity(keyname=k, value=json.loads(v))
                entity.put()

            for k in self.__dels:
                results = GAEEntity.all().filter('keyname =', k)

                if len(results) == 0:
                    pass

                else:
                    for entity in results:
                        entity.delete()

        def close(self): pass

except ImportError: pass